﻿// <copyright file="ItemData.cs" company="Oleg V. Polikarpotchkin">
// Copyright © 2008 Oleg V. Polikarpotchkin. All Right Reserved
// </copyright>
// <author>Oleg V. Polikarpotchkin</author>
// <email>ov-p@yandex.ru</email>
// <date>2008-12-23</date>
// <summary>OpenWPFChart library. ItemData is the abstract base class of all Data classes.</summary>
// <revision>$Id$</revision>

using System;
using System.ComponentModel; // For INotifyPropertyChanged

namespace OpenWPFChart.Parts
{
	/// <summary>
	/// Abstract base class of all OpenWPFChart Data classes.
	/// </summary>
	public abstract class ItemData : ICloneable, INotifyPropertyChanged
	{
		#region ItemName
		string itemName;
		/// <summary>
		/// Gets or sets the <see cref="ItemName"/> property.
		/// </summary>
		/// <value>Item Name string or <c>null</c>.</value>
		/// <remarks>The name of the item.</remarks>
		public string ItemName 
		{
			get { return itemName; }
			set
			{
				if (itemName != value)
				{
					itemName = value;
					NotifyPropertyChanged("ItemName");
				}
			}
		}
		#endregion ItemName

		/// <summary>
		/// Gets the type of the <paramref name="index"/> dimension.
		/// </summary>
		/// <param name="index">Dimension index.</param>
		/// <returns><paramref name="index"/>-th dimension base type.</returns>
		/// <remarks>
		/// <see cref="ItemData"/> represents n-dimensional data and each dimension has
		/// its own distinct base type (e.g. <c>double</c>, <c>DateTime</c>
		/// or <c>object</c>).
		/// </remarks>
		public abstract Type GetDimensionType(int index);

		/// <summary>
		/// Determines whether the series of the <paramref name="index"/>-th dimension of this object
		/// and of the <paramref name="item"/> specified are equal.
		/// </summary>
		/// <param name="index">Dimension index.</param>
		/// <param name="item">The item.</param>
		/// <returns><c>true</c> if series are equal; otherwise, <c>false</c>.</returns>
		public abstract bool DimensionEqual(int index, ItemData item);

		#region ICloneable Members
		/// <summary>
		/// Creates a new object that is a copy of the current instance.
		/// </summary>
		/// <returns>
		/// A new object that is a copy of this instance.
		/// </returns>
		/// <remarks>
		/// <para>Override <see cref="CloneInternal"/> in derived classes to provide deep cloning
		/// facility.</para>
		/// </remarks>
		public object Clone()
		{
			return CloneInternal();
		}

		/// <summary>
		/// Creates a new object that is a copy of the current instance.
		/// </summary>
		/// <returns>
		/// A new object that is a copy of this instance.
		/// </returns>
		/// <remarks>This method is designed to provide the deep cloning facility if desired.</remarks>
		protected virtual object CloneInternal()
		{
			ItemData clone = MemberwiseClone() as ItemData;
			clone.PropertyChanged = null;
			return clone;
		}
		#endregion ICloneable Members

		#region INotifyPropertyChanged Members
		/// <summary>
		/// Occurs when a property value changes.
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Notifies the property changed.
		/// </summary>
		/// <param name="propertyName">Name of the property.</param>
		protected void NotifyPropertyChanged(string propertyName)
		{
			if (PropertyChanged != null) 
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}
		#endregion INotifyPropertyChanged Members
	}
}
